package com.demo.controller;


import com.demo.config.TaskPoolConfig;
import com.demo.dao.EsUserDao;
import com.demo.entity.EsUser;
import com.demo.service.FileService;
import com.demo.service.UserDiseaseService;
import com.demo.service.UserService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.*;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.collapse.CollapseBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;


@RestController
@RequestMapping("test")
public class TestController {
    @Autowired
    private UserService userService;
    @Autowired
    private UserDiseaseService userDiseaseService;
    @Autowired
    private FileService fileService;
    @Autowired
    private EsUserDao esUserDao;
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private TaskPoolConfig executor;

    /**
     * 读取Excel，写入数据
     *
     * @param file
     * @throws IOException
     */
    @RequestMapping("test1")
    public void test1(@RequestPart(name = "file") MultipartFile file) throws IOException {
        fileService.readeExcel(file);
    }

    /**
     * 删除所有数据
     */
    @RequestMapping("test2")
    public void test2() {
        userService.deleteAll();
        userDiseaseService.deleteAll();
    }

    @RequestMapping("test3")
    public void test3(String name, Integer age) {
        EsUser esUser = new EsUser();
        esUser.setName(name);
        esUser.setAge(age);
        esUser.setSex("男");
        esUserDao.save(esUser);
    }

    @RequestMapping("test33")
    public void test33(String name, Integer age) {
        for (int i = 0; i < 1000000; i++) {
            System.out.println("已完成：" + i);
            //多线程处理加快速度
            executor.taskExecutor().execute(new Runnable() {
                @Override
                public void run() {
                    EsUser esUser = new EsUser();
                    esUser.setName(name);
                    esUser.setAge(age);
                    esUser.setSex("男");
                    esUserDao.save(esUser);
                }
            });
        }
    }


    @RequestMapping("test4")
    public void test4() {
        Iterable<EsUser> all = esUserDao.findAll();
        all.forEach(s -> System.out.println(s));
    }

    @RequestMapping("test5")
    public Long test5() {
        long count = esUserDao.count();
        return count;
    }


    /**
     * es按条件查询
     */
    @RequestMapping("test6")
    public void test6() {
        //2.创建 SearchSourceBuilder条件构造。
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder qb = QueryBuilders.boolQuery();
        // 单个条件过滤
        qb.filter(QueryBuilders.termQuery("age", 5));
        // 大于、小于
        RangeQueryBuilder range = QueryBuilders.rangeQuery("age");
        range.gte(0);
        range.lt(100);
        qb.filter(range);

        searchSourceBuilder.query(qb);
        //从第几条开始
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(500);

        //排序
        searchSourceBuilder.sort("age", SortOrder.ASC);

        //指定需要返回或者排除的字段
        String[] includes = {"id", "name"};
        String[] excludes = {};
        searchSourceBuilder.fetchSource(includes, excludes);

        //1.创建 SearchRequest搜索请求,并指定要查询的索引
        SearchRequest searchRequest = new SearchRequest("user-table");
        searchRequest.source(searchSourceBuilder);

        try {
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            System.out.println("花费的时长：" + response.getTook());

            SearchHits hits = response.getHits();
            hits.forEach(x -> {
                System.out.println("查询结果 --> " + x.getId() + "****" + x.getSourceAsString());
            });
        } catch (IOException e) {

        }
    }

    /**
     * 聚合查询-count
     */
    @RequestMapping("test7")
    public void test7() {
        //2.创建 SearchSourceBuilder条件构造。
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder qb = QueryBuilders.boolQuery();
        // 单个条件过滤
        qb.filter(QueryBuilders.termQuery("age", 5));
        searchSourceBuilder.query(qb);

        //统计数量-年龄
        ValueCountAggregationBuilder userIdCountBuilder = AggregationBuilders.count("num").field("age");

        searchSourceBuilder.aggregation(userIdCountBuilder);

        //1.创建 SearchRequest搜索请求,并指定要查询的索引
        SearchRequest searchRequest = new SearchRequest("user-table");
        //SearchRequest搜索请求,并指定要查询的索引
        searchRequest.source(searchSourceBuilder);
        System.out.println(searchRequest.source().toString());

        try {
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            Aggregations aggregations = response.getAggregations();//获取聚合结果
            ValueCount valueCount = aggregations.get("num");//获取value_count聚合返回的对象
            String key = valueCount.getName();//获取聚合名称
            long count = valueCount.getValue();//获取聚合值
            System.out.println("key=" + key + ",count=" + count);//打印结果
        } catch (IOException e) {
        }
    }


    /**
     * 聚合查询-sum
     */
    @RequestMapping("test8")
    public void test8() {
        //2.创建 SearchSourceBuilder条件构造。
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //sum-年龄
        SumAggregationBuilder ageSumBuilder = AggregationBuilders.sum("sum").field("age");
        searchSourceBuilder.aggregation(ageSumBuilder);

        //1.创建 SearchRequest搜索请求,并指定要查询的索引
        SearchRequest searchRequest = new SearchRequest("user-table");
        //SearchRequest搜索请求,并指定要查询的索引
        searchRequest.source(searchSourceBuilder);
        System.out.println(searchRequest.source().toString());

        try {
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            Aggregations aggregations = response.getAggregations();//获取聚合结果

            Sum sum = aggregations.get("sum");//获取value_count聚合返回的对象
            String key = sum.getName();//获取聚合名称
            double sumVal = sum.getValue();//获取聚合值
            System.out.println("key=" + key + ",count=" + sumVal);//打印结果

        } catch (IOException e) {
        }
    }


    /**
     * 聚合查询-sum+count
     */
    @RequestMapping("test9")
    public void test9() {
        //2.创建 SearchSourceBuilder条件构造。
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //统计数量-年龄
        SumAggregationBuilder ageSumBuilder = AggregationBuilders.sum("sum").field("age");
        searchSourceBuilder.aggregation(ageSumBuilder);

        //count-年龄c
        ValueCountAggregationBuilder countBuilder = AggregationBuilders.count("num").field("age");
        searchSourceBuilder.aggregation(countBuilder);

        //1.创建 SearchRequest搜索请求,并指定要查询的索引
        SearchRequest searchRequest = new SearchRequest("user-table");
        //SearchRequest搜索请求,并指定要查询的索引
        searchRequest.source(searchSourceBuilder);
        System.out.println(searchRequest.source().toString());

        try {
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            System.out.println("花费的时长：" + response.getTook());

            Aggregations aggregations = response.getAggregations();//获取聚合结果
            Sum sum = aggregations.get("sum");//获取value_count聚合返回的对象
            String key = sum.getName();//获取聚合名称
            double sumVal = sum.getValue();//获取聚合值
            System.out.println("key=" + key + ",count=" + sumVal);//打印结果

            System.out.println("************************************");

            ValueCount valueCount = aggregations.get("num");//获取value_count聚合返回的对象
            String key2 = valueCount.getName();//获取聚合名称
            long count = valueCount.getValue();//获取聚合值
            System.out.println("key=" + key2 + ",count=" + count);//打印结果
        } catch (IOException e) {
        }
    }


    /**
     * 聚合查询-bucket(group by)
     */
    @RequestMapping("test10")
    public void test10() {
        //2.创建 SearchSourceBuilder条件构造。
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //统计数量-年龄
        TermsAggregationBuilder ageGroupBuilder = AggregationBuilders.terms("ageGroup").field("age").size(2);
        searchSourceBuilder.aggregation(ageGroupBuilder);

        //1.创建 SearchRequest搜索请求,并指定要查询的索引
        SearchRequest searchRequest = new SearchRequest("user-table");
        //SearchRequest搜索请求,并指定要查询的索引
        searchRequest.source(searchSourceBuilder);
        System.out.println(searchRequest.source().toString());

        try {
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            System.out.println("花费的时长：" + response.getTook());

            Aggregations aggregations = response.getAggregations();
            System.out.println("aggregations：" + aggregations);
            ParsedTerms jobGroup = aggregations.get("ageGroup");
            System.out.println("字段：" + jobGroup.getName());
            List<? extends Terms.Bucket> buckets = jobGroup.getBuckets();
            for (Terms.Bucket bucket : buckets) {
                System.out.println("*******************************");
                System.out.println("getKey：" + bucket.getKey());
                System.out.println("getKeyAsString：" + bucket.getKeyAsString());
                System.out.println("getDocCount：" + bucket.getDocCount());
            }
        } catch (IOException e) {
        }
    }


    /**
     * 聚合查询-bucket(group by)-order
     */
    @RequestMapping("test11")
    public void test11() {
        //2.创建 SearchSourceBuilder条件构造。
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //统计数量-年龄
        TermsAggregationBuilder ageGroupBuilder = AggregationBuilders.terms("ageGroup").field("age").order(BucketOrder.aggregation("_key", true));
        searchSourceBuilder.aggregation(ageGroupBuilder);
        searchSourceBuilder.from(1);
        searchSourceBuilder.size(2);

        //1.创建 SearchRequest搜索请求,并指定要查询的索引
        SearchRequest searchRequest = new SearchRequest("user-table");
        //SearchRequest搜索请求,并指定要查询的索引
        searchRequest.source(searchSourceBuilder);
        System.out.println(searchRequest.source().toString());

        try {
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            System.out.println("花费的时长：" + response.getTook());

            Aggregations aggregations = response.getAggregations();
            System.out.println("aggregations：" + aggregations);
            ParsedTerms jobGroup = aggregations.get("ageGroup");
            System.out.println("字段：" + jobGroup.getName());
            List<? extends Terms.Bucket> buckets = jobGroup.getBuckets();
            for (Terms.Bucket bucket : buckets) {
                System.out.println("*******************************");
                System.out.println("getKey：" + bucket.getKey());
                System.out.println("getKeyAsString：" + bucket.getKeyAsString());
                System.out.println("getDocCount：" + bucket.getDocCount());
            }
        } catch (IOException e) {
        }
    }


    /**
     * 聚合查询-分页
     */
    @RequestMapping("test12")
    public void test12() throws IOException {
        //按照spu进行分组
        CollapseBuilder collapseBuilder = new CollapseBuilder("age");
        SearchRequest searchRequest = new SearchRequest();//新建搜索请求

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.collapse(collapseBuilder);
        //从第几条开始
        searchSourceBuilder.from(1);
        searchSourceBuilder.size(2);
        searchSourceBuilder.sort("age", SortOrder.ASC);

        searchRequest.source(searchSourceBuilder);//设置查询

        System.out.println(searchRequest.source().toString());

        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//执行搜索
        SearchHits searchHits = searchResponse.getHits();//获取搜索结果集
        for (SearchHit searchHit : searchHits) {//遍历搜索结果集
            String index = searchHit.getIndex();//获取索引名称
            String id = searchHit.getId();//获取文档_id
            Float score = searchHit.getScore();//获取得分
            String source = searchHit.getSourceAsString();//获取文档内容
            System.out.println("index=" + index + ",id=" + id + ",score=" + score + ",source=" + source);//打印数据
        }
    }

    @RequestMapping("test13")
    public void test13(int page, int size) throws IOException {


    }
}
